package com.csust.automaticteach.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.csust.automaticteach.app.common.ExerciseEvaluateApp;
import com.csust.automaticteach.app.student.ExerciseGenerateApp;
import com.csust.automaticteach.exception.BusinessException;
import com.csust.automaticteach.exception.ErrorCode;
import com.csust.automaticteach.exception.ThrowUtils;
import com.csust.automaticteach.model.dto.generatequestion.AddGenerateQuestionRequest;
import com.csust.automaticteach.model.dto.generatequestion.GenerateQuestionQueryDTO;
import com.csust.automaticteach.model.dto.generatequestion.JudgeGenerateQuestionRequest;
import com.csust.automaticteach.model.entity.*;
import com.csust.automaticteach.model.vo.generatequestion.GenerateQuestionPageVO;
import com.csust.automaticteach.model.vo.generatequestion.GenerateQuestionResponse;
import com.csust.automaticteach.model.vo.generatequestion.GenerateQuestionVO;
import com.csust.automaticteach.model.vo.generatequestion.JudgeGenerateQuestionVO;
import com.csust.automaticteach.service.*;
import com.csust.automaticteach.mapper.GenerateQuestionMapper;
import com.csust.automaticteach.utils.ParseGenerateExerciseJsonUtil;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

import static cn.hutool.json.JSONUtil.toJsonStr;
import static com.csust.automaticteach.constant.OrderConstant.ASC;

/**
* @author 钰玟
* @description 针对表【t_generate_question(题目生成)】的数据库操作Service实现
* @createDate 2025-06-20 10:52:44
*/
@Service
public class GenerateQuestionServiceImpl extends ServiceImpl<GenerateQuestionMapper, GenerateQuestion>
    implements GenerateQuestionService{
    @Resource
    private ExerciseGenerateApp exerciseGenerateApp;
    @Resource
    private ExerciseEvaluateApp exerciseEvaluateApp;

    @Resource
    private ParseGenerateExerciseJsonUtil parseGenerateExerciseJsonUtil;
    @Resource
    private ErrorPracticeService errorPracticeService;
    @Resource
    private PracticeSituationService practiceSituationService;
    @Resource
    private ExercisesService exercisesService;
    @Resource
    private ExercisesSetsService exercisesSetsService;
    @Resource
    private SetExercisesService setExercisesService;


    @Override
    public List<GenerateQuestionVO> getGenerateQuestionVOList(GenerateQuestion generateQuestion) {
        // 0.注意这是一套题的答案  ["A","B","C","D","E"]
        String userAnsJson = generateQuestion.getUserAns();
        List<String> userAnsList = new ArrayList<>();
        //非空判断
        if(StrUtil.isNotBlank(userAnsJson) &&ObjUtil.isNotNull(userAnsJson)) {
            userAnsList = JSONUtil.toList(userAnsJson, String.class);
//            useransList = parseGenerateExerciseJsonUtil.parseJson(userAnsJson, String.class);
        }
        //1.根据实体类中的content字段获取到题目列表 响应字符串  GenerateQuestionResponse
        String content = generateQuestion.getContent();
        List<GenerateQuestionResponse> generateQuestionResponseList = parseGenerateExerciseJsonUtil.parseJson(content,GenerateQuestionResponse.class);
        List<GenerateQuestionVO> generateQuestionVOList = generateQuestionResponseList.stream()
                .map(generateQuestionResponse -> {
                     GenerateQuestionVO generateQuestionVO = new GenerateQuestionVO();
                     //大部分的属性拷贝
                     BeanUtils.copyProperties(generateQuestionResponse, generateQuestionVO);
                     //单独设置属性 1.题目标题 2.id  3.用户提交的答案 4. 题目类型
                     generateQuestionVO.setTitle(generateQuestion.getTitle());
                     generateQuestionVO.setId(generateQuestion.getId());
                    generateQuestionVO.setType(generateQuestion.getType());
                    generateQuestionVO.setCreateTime(generateQuestion.getCreateTime());//设置时间
                    generateQuestionVO.setKnowledgePoints(JSONUtil.toJsonStr(generateQuestionResponse.getKnowledgePoints()));//设置知识点
                     return generateQuestionVO;
                }).toList();
        //设置用户答案
        for (int i = 0; i < userAnsList.size(); i++) {
            String ans = userAnsList.get(i);
            generateQuestionVOList.get(i).setUserAns(ans);
        }
        //单独设置变化的id
        for (int i = 0; i < generateQuestionVOList.size(); i++) {
            generateQuestionVOList.get(i).setId(generateQuestion.getId()+i);//首个的id是与generateQuestion相同
        }
        return generateQuestionVOList;

    }
    @Transactional//事务
    public List<Exercises> getGenerateQuestionRefactoring(AddGenerateQuestionRequest addGenerateQuestionRequest, User loginUser){
        String currentTime  = String.valueOf(System.currentTimeMillis());
        //构造chatId
        Long userId = loginUser.getId();
        String chatId = userId +currentTime;
        //调用生成题目服务
        String content = exerciseGenerateApp.doGenerate(addGenerateQuestionRequest, chatId);
        String type = addGenerateQuestionRequest.getExams().get(0).getType();
        String knowledgePoint = addGenerateQuestionRequest.getKnowledgePoint();
        String title = knowledgePoint + "练习题";
        List<GenerateQuestionResponse> generateQuestionResponseList = parseGenerateExerciseJsonUtil.parseJson(content,GenerateQuestionResponse.class);
        //分解每一道题目插入exercises表
        List<Exercises> exercisesList = generateQuestionResponseList.stream().map(generateQuestionResponse -> {
            Exercises exercises = new Exercises();
            BeanUtils.copyProperties(generateQuestionResponse, exercises);
            String options = toJsonStr(generateQuestionResponse.getOptions());
            exercises.setOptions(options);
            exercises.setUserId(loginUser.getId());
            exercises.setTitle(title);
            exercises.setType(type);
            List<String> knowledgePoints = generateQuestionResponse.getKnowledgePoints();
            if(CollUtil.isNotEmpty(knowledgePoints)) {
                exercises.setKnowledgePoint(knowledgePoints.get(0));
            }else{
                exercises.setKnowledgePoint(knowledgePoint);
            }
            return exercises;
        }).toList();
        boolean saved1 = exercisesService.saveBatch(exercisesList);
        //组成套题
        ExercisesSets exercisesSets = ExercisesSets.builder().title(title).userId(userId).build();
        boolean saved2 = exercisesSetsService.save(exercisesSets);
        //组成套题的关联
        List<SetExercises> setExercisesList = setExercisesService.getSetExercisesList(exercisesList, exercisesSets.getId());
        boolean saved3 = setExercisesService.saveBatch(setExercisesList);
        ThrowUtils.throwIf(!saved1 || !saved2 || !saved3, ErrorCode.OPERATION_ERROR);
        return exercisesList;
    }
    @Override
    public List<GenerateQuestionVO> getGenerateQuestion(AddGenerateQuestionRequest addGenerateQuestionRequest, User loginUser) {
        String currentTime  = String.valueOf(System.currentTimeMillis());
        //构造chatId
        String chatId = loginUser.getId()+currentTime;
        //调用生成题目服务
        String content = exerciseGenerateApp.doGenerate(addGenerateQuestionRequest, chatId);
        GenerateQuestion generateQuestion = new GenerateQuestion();
        //拷贝属性
        BeanUtil.copyProperties(addGenerateQuestionRequest, generateQuestion);
        //设置题目生成人
        generateQuestion.setUserId(loginUser.getId());
        //设置题目内容 ，为json字符串
        generateQuestion.setContent(content);
        //设置标题 title = 用户名+题目数量+题目类型
//        String title = loginUser.getUserName() + "生成的有关"+ addGenerateQuestionRequest.getTopic() + "题";
        String title =  addGenerateQuestionRequest.getKnowledgePoint() + "练习题";
        generateQuestion.setTitle(title);

        boolean isSave = this.save(generateQuestion);

        if (!isSave) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR);
        }
        //region
        //主键Id ，主键回显
//        Long id = generateQuestion.getId();
        //创建vo列表
        //解析字符串
//        List<GenerateQuestionResponse> generateQuestionResponseList = parseGenerateExerciseJsonUtil.parseJson(content,GenerateQuestionResponse.class);
//        List<GenerateQuestionVO> results = generateQuestionResponseList.stream()
//                .map(generateQuestionResponse -> {
//                    GenerateQuestionVO generateQuestionVO = new GenerateQuestionVO();
//                    BeanUtils.copyProperties(generateQuestionResponse, generateQuestionVO);
//                    generateQuestionVO.setTitle(title);
//                    // 主键回显
//                    generateQuestionVO.setId(id);
//                    return generateQuestionVO;
//                }).collect(Collectors.toList());
        //返回视图对象
//        return results;
        return this.getGenerateQuestionVOList(generateQuestion);
    }

    @Transactional//开启事务
    @Override
    public List<JudgeGenerateQuestionVO> judgeGenerateQuestion(JudgeGenerateQuestionRequest judgeGenerateQuestionRequest) {
 /*       //1. 根据获取题目信息
        String questionId = judgeGenerateQuestionRequest.getId();
        //2. 获取 元题目信息
        GenerateQuestion generateQuestion = this.getById(questionId);
        Long userId = generateQuestion.getUserId();
        List<GenerateQuestionResponse> generateQuestionResponseList = parseGenerateExerciseJsonUtil.parseJson(generateQuestion.getContent(),GenerateQuestionResponse.class);
        //3. 构造ai的判断 请求体
        List<JudgeGenerateQuestionForAIRequest> judgeGenerateQuestionForAIRequests = generateQuestionResponseList.stream()
                .map(generateQuestionResponse -> {
                    JudgeGenerateQuestionForAIRequest judgeForAI = new JudgeGenerateQuestionForAIRequest();
                    String question = generateQuestionResponse.getContent();
                    String rightAns = generateQuestionResponse.getAnswer();
                    //设置题目
                    judgeForAI.setQuestion(question);
                    //设置正确答案
                    judgeForAI.setRightAns(rightAns);
                    judgeForAI.setId(questionId);
                    //设置题目选项，选择题，防止ai出现幻觉
                    judgeForAI.setOptions(generateQuestionResponse.getOptions());
                    //设置知识点，增强ai的上下文能力
                    judgeForAI.setKnowledgePoints(generateQuestionResponse.getKnowledgePoints());
                    return judgeForAI;
                }).collect(Collectors.toList());
        List<String> ansList = judgeGenerateQuestionRequest.getAnsList();
        //4. 设置用户答案
        for (int i = 0; i < ansList.size(); i++) {
            JudgeGenerateQuestionForAIRequest judgeGenerateQuestionForAIRequest = judgeGenerateQuestionForAIRequests.get(i);
            String userAns = ansList.get(i);
            judgeGenerateQuestionForAIRequest.setUserAns(userAns);
        }
        String requestJson = toJsonStr(judgeGenerateQuestionForAIRequests);
        String chatId = UUID.randomUUID().toString();
        //5. 发给ai助手
        String result = exerciseEvaluateApp.doEvaluate(requestJson, chatId);
        //只包含了isCorrect、 suggestion
        List<JudgeGenerateQuestionVO> judgeGenerateQuestionVOS = parseGenerateExerciseJsonUtil.parseJson(result, JudgeGenerateQuestionVO.class);
        // 6. 复制其他属性，explanation，knowledgePoints
        for (int i = 0; i < generateQuestionResponseList.size(); i++) {
            JudgeGenerateQuestionVO judgeGenerateQuestionVO = judgeGenerateQuestionVOS.get(i);
            GenerateQuestionResponse generateQuestionResponse = generateQuestionResponseList.get(i);
            BeanUtil.copyProperties(generateQuestionResponse, judgeGenerateQuestionVO);
            judgeGenerateQuestionVO.setId(Long.valueOf(questionId));
        }
        //7.更新相关表  1. t_generate_question  2. t_error_practice  3.t_practice_situation
        //7.1 设置的属性为 1. userAns  2. accuracyRate
        generateQuestion.setUserAns(toJsonStr(ansList));//设置用户答案
        long rightCount = judgeGenerateQuestionVOS.stream().filter(JudgeGenerateQuestionVO::isCorrect).count();//计算正确数量
        Integer totalCount = generateQuestion.getCount();//获取总数
        //7.2 计算正确率
        double accuracyRate = ((double) rightCount / totalCount) * 100 ;
        generateQuestion.setAccuracyRate(String.valueOf(accuracyRate));
        //7.3 更新
        boolean saved1 = this.saveOrUpdate(generateQuestion);
        //8 错题本的更新  errorPracticeService
        //8.1得到错误题的索引 设置相关属性
        List<ErrorPractice> errorPracticeList = new ArrayList<>();
        List<Integer> errorIndex = new ArrayList<>();
        for (int i = 0; i < judgeGenerateQuestionVOS.size(); i++) {
            JudgeGenerateQuestionVO judgeGenerateQuestionVO = judgeGenerateQuestionVOS.get(i);
            if (!judgeGenerateQuestionVO.isCorrect()){
                ErrorPractice errorPractice = new ErrorPractice();
                String explanation = judgeGenerateQuestionVO.getExplanation();
                String suggestion = judgeGenerateQuestionVO.getSuggestion();
                List<String> knowledgePoints = judgeGenerateQuestionVO.getKnowledgePoints();
                String jsonKnowledgePoints = JSONUtil.toJsonStr(knowledgePoints);
                errorPractice.setExplanation( explanation);
                errorPractice.setSuggestion(suggestion);
                errorPractice.setKnowledgePoints(jsonKnowledgePoints);
                errorPractice.setUserId(userId);
                errorPractice.setReviewCount(1);
                //加入错误题
                errorPracticeList.add(errorPractice);
                //添加至错误索引列表
                errorIndex.add(i);
            }
        }
        //8.2  设置其他属性
        List<GenerateQuestionVO> generateQuestionVOList = this.getGenerateQuestionVOList(generateQuestion);
        for (int i = 0; i < errorIndex.size(); i++) {
            GenerateQuestionVO generateQuestionVO = generateQuestionVOList.get(errorIndex.get(i));
            ErrorPractice errorPractice = errorPracticeList.get(i);
            BeanUtil.copyProperties(generateQuestionVO, errorPractice, "id");//忽略 id
        }
        //8.3 更新
        if (!errorPracticeList.isEmpty()) {
            boolean saved2 = errorPracticeService.saveOrUpdateBatch(errorPracticeList);
            ThrowUtils.throwIf(!saved2, ErrorCode.OPERATION_ERROR);
        }

        //9. practice_situation 的更新
        //9.1 获取错误知识点
        List<String> errorKnowledgePoints = new ArrayList<>();
        for (ErrorPractice errorPractice : errorPracticeList) {
            String knowledgePoints = errorPractice.getKnowledgePoints();
            List<String> list = JSONUtil.toList(knowledgePoints, String.class);
            errorKnowledgePoints.addAll(list);
        }
        PracticeSituationUpdateRequest practiceSituationUpdateRequest = new PracticeSituationUpdateRequest();
        practiceSituationUpdateRequest.setUserId(userId);
        practiceSituationUpdateRequest.setErrorPointsList(errorKnowledgePoints);
        practiceSituationUpdateRequest.setTotalNum(Long.valueOf(totalCount));
        practiceSituationUpdateRequest.setRightNum(rightCount);
        Boolean saved3 = practiceSituationService.updatePracticeSituation(practiceSituationUpdateRequest);
        ThrowUtils.throwIf(!saved1 || !saved3, ErrorCode.OPERATION_ERROR);
        return judgeGenerateQuestionVOS;*/
        List<JudgeGenerateQuestionVO> judgeGenerateQuestionVOS = new ArrayList<>();
        return judgeGenerateQuestionVOS;
    }

    @Override
    public QueryWrapper<GenerateQuestion> getGenerateQuestionQueryWrapper(GenerateQuestionQueryDTO generateQuestionQueryDTO) {
        //从DTO中获取参数
        Long id = generateQuestionQueryDTO.getId();
        String title = generateQuestionQueryDTO.getTitle();
        Long userId = generateQuestionQueryDTO.getUserId();
        String knowledgePoint = generateQuestionQueryDTO.getKnowledgePoint();
        String sortField = generateQuestionQueryDTO.getSortField();
        String sortOrder = generateQuestionQueryDTO.getSortOrder();
        //封装wrapper对象
        QueryWrapper<GenerateQuestion> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(ObjUtil.isNotNull(id),"id",id);
        queryWrapper.like(StrUtil.isNotBlank(title),"title",title);
        queryWrapper.eq(ObjUtil.isNotNull(userId),"userId",userId);
        queryWrapper.like(StrUtil.isNotBlank(knowledgePoint),"knowledgePoint",knowledgePoint);
        queryWrapper.orderBy(StrUtil.isNotEmpty(sortField),sortOrder.equals(ASC),sortField);
        //返回query
        return queryWrapper;
    }

    @Override
    public List<GenerateQuestionPageVO> getGenerateQuestionPageVOList(List<GenerateQuestion> records) {
        return records.stream().map(generateQuestion -> {
            GenerateQuestionPageVO generateQuestionPageVO = new GenerateQuestionPageVO();
            BeanUtils.copyProperties(generateQuestion, generateQuestionPageVO);
            return generateQuestionPageVO;
        }).toList();
    }


}




